﻿// <copyright file="Service1.svc.cs" company="company"> 
// (C) 2010 . All rights reserved
// </copyright>
// <author>Lukasz Bartczak</author>

namespace WcfService1
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using DataTransfer;

    /// <summary>   
    /// Service implementation class
    /// </summary>
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Services : IServices
    {
        /// <summary>
        /// Implementation of the contract od the Gets the child and opiekun by firstname method.
        /// </summary>
        /// <param name="firstname">The firstname of the child</param>
        /// <param name="lastname">The Lastname of the child</param>
        /// <returns>
        /// List of generic collection of dziecko and opiekun
        /// </returns>
        public CustomCollection<DzieckoAndOpiekun> GetChildAndOpiekunByFirstnameLastname(string firstname, string lastname)
        {
            try
            {
                CustomCollection<DzieckoAndOpiekun> result = new CustomCollection<DzieckoAndOpiekun>();
                DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
                IEnumerable<DzieckoAndOpiekun> resultV;

                if (String.IsNullOrEmpty(firstname) && !String.IsNullOrEmpty(lastname))
                {
                    resultV = from p in db.Dziecko.AsEnumerable()
                              where lastname == p.Nazwisko
                              select new DzieckoAndOpiekun(
                            p.Imie,
                            p.Nazwisko,
                            p.Opiekun.Imie,
                            p.Opiekun.Nazwisko);
                    List<DzieckoAndOpiekun> l = resultV.ToList();
                    result.AddRange(l);
                }

                if (!String.IsNullOrEmpty(firstname) && !String.IsNullOrEmpty(lastname))
                {
                    resultV = from p in db.Dziecko.AsEnumerable()
                              where firstname == p.Imie && lastname == p.Nazwisko
                              select new DzieckoAndOpiekun(
                             p.Imie,
                             p.Nazwisko,
                             p.Opiekun.Imie,
                             p.Opiekun.Nazwisko);
                    List<DzieckoAndOpiekun> l = resultV.ToList();
                    result.AddRange(l);
                }

                if (!String.IsNullOrEmpty(firstname) && String.IsNullOrEmpty(lastname))
                {
                    resultV = from p in db.Dziecko.AsEnumerable()
                              where firstname == p.Imie
                              select new DzieckoAndOpiekun(
                             p.Imie,
                             p.Nazwisko,
                             p.Opiekun.Imie,
                             p.Opiekun.Nazwisko);
                    List<DzieckoAndOpiekun> l = resultV.ToList();
                    result.AddRange(l);
                }
                return result;
            }
            catch (FaultException fe)
            {
                throw new FaultException(fe.Reason, fe.Code, "Exception in GetChildAndOpiekunByFirstnameLastname");
            }
            catch (CommunicationException cex)
            {
                throw new CommunicationException("Exception in GetChildAndOpiekunByFirstnameLastname " + cex.Message, cex.InnerException);
            }
            catch (Exception exe)
            {
                throw new Exception("Exception in GetChildAndOpiekunByFirstnameLastname " + exe.Message, exe.InnerException);
            }
        }

        /// <summary>
        /// Gets the peyments by child and opiekun.
        /// </summary>
        /// <param name="dzieckaFirstname">The dziecka firstname.</param>
        /// <param name="dzieckaLastname">The dziecka lastname.</param>
        /// <param name="opiekunaFirstname">The opiekuna firstname.</param>
        /// <param name="opiekunaLastname">The opiekuna lastname.</param>
        /// <returns>Collection of Payment by dziecko.</returns>
        public CustomCollection<Payments> GetPeymentsByChildAndOpiekun(string dzieckaFirstname, string dzieckaLastname, string opiekunaFirstname, string opiekunaLastname)
        {
            try
            {
                CustomCollection<Payments> payments = new CustomCollection<Payments>();
                DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
                IEnumerable<int> idDziecList = null;

                idDziecList = from dzieckoTmp in db.Dziecko
                              where dzieckoTmp.Imie.Contains(dzieckaFirstname) &&
                              dzieckoTmp.Nazwisko.Contains(dzieckaLastname) &&
                              dzieckoTmp.Opiekun.Imie.Contains(opiekunaFirstname) &&
                              dzieckoTmp.Opiekun.Nazwisko == opiekunaLastname
                              select dzieckoTmp.IdDziecko;

                int idDziec = idDziecList.SingleOrDefault();
                var naleznosci = (from nalTmp in db.Naleznosci
                                  where nalTmp.idDziecko == idDziec
                                  select new Payments
                                  {
                                      DzieckoImie = nalTmp.Dziecko.Imie,
                                      DzieckoNazwisko = nalTmp.Dziecko.Nazwisko,
                                      Miesiac = nalTmp.Miesiace.Nazwa,
                                      Kwota = nalTmp.Kwota,
                                      RodzajOpłaty = nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                      TypOplaty = nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                      DataRozliczenia = nalTmp.DataRozliczenia,
                                      TerminPlatnosci = nalTmp.TerminPlatnosci,
                                  }).ToList();
                List<Payments> l = naleznosci;
                payments.AddRange(l);
                return payments;
            }
            catch (FaultException fe)
            {
                throw new FaultException(fe.Reason, fe.Code, "Exception in GetPeymentsByChildAndOpiekun");
            }
            catch (CommunicationException cex)
            {
                throw new CommunicationException("Exception in GetPeymentsByChildAndOpiekun " + cex.Message, cex.InnerException);
            }
            catch (Exception exe)
            {
                throw new Exception("Exception in GetPeymentsByChildAndOpiekun " + exe.Message, exe.InnerException);
            }
        }

        /// <summary>
        /// Gets the peyments by opiekun.
        /// </summary>
        /// <param name="opiekunFirstname">The opiekun firstname.</param>
        /// <param name="opiekunLastname">The opiekun lastname.</param>
        /// <returns>Collection of Payment by dziecko.</returns>
        public CustomCollection<Payments> GetPeymentsByOpiekun(string opiekunFirstname, string opiekunLastname)
        {
            try
            {
                CustomCollection<Payments> payments = new CustomCollection<Payments>();
                DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
                IEnumerable<int> opiekunId = (from opiekun in db.Opiekun
                                              where opiekun.Imie.Contains(opiekunFirstname) &&
                                              opiekun.Nazwisko.Contains(opiekunLastname)
                                              select opiekun.idOpiekun).ToList();
                IEnumerable<int> idDziecList = null;
                idDziecList = (from dzieckoTmp in db.Dziecko
                               where dzieckoTmp.Opiekun.idOpiekun == opiekunId.FirstOrDefault()
                               select dzieckoTmp.IdDziecko).ToList();
                foreach (int idDziecka in idDziecList)
                {
                    var naleznosci = (from nalTmp in db.Naleznosci
                                      where nalTmp.idDziecko == idDziecka
                                      select new Payments
                                      {
                                          DzieckoImie = nalTmp.Dziecko.Imie,
                                          DzieckoNazwisko = nalTmp.Dziecko.Nazwisko,
                                          Miesiac = nalTmp.Miesiace.Nazwa,
                                          Kwota = nalTmp.Kwota,
                                          RodzajOpłaty = nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                          TypOplaty = nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                          DataRozliczenia = nalTmp.DataRozliczenia,
                                          TerminPlatnosci = nalTmp.TerminPlatnosci,
                                      }).ToList();
                    List<Payments> l = naleznosci;
                    payments.AddRange(l);
                }
                return payments;
            }
            catch (FaultException fe)
            {
                throw new FaultException(fe.Reason, fe.Code, "Exception in GetPeymentsByOpiekun");
            }
            catch (CommunicationException cex)
            {
                throw new CommunicationException("Exception in GetPeymentsByOpiekun " + cex.Message, cex.InnerException);
            }
            catch (Exception exe)
            {
                throw new Exception("Exception in GetPeymentsByOpiekun " + exe.Message, exe.InnerException);
            }
        }

        /// <summary>
        /// Adds the child and opiekun.
        /// </summary>
        /// <param name="dzieckaFirstname">The dziecka firstname.</param>
        /// <param name="dzieckaLastname">The dziecka lastname.</param>
        /// <param name="idGrupy">The id grupy.</param>
        /// <param name="opiekunaFirstname">The opiekuna firstname.</param>
        /// <param name="opiekunaLastname">The opiekuna lastname.</param>
        /// <param name="tel">The telephone number.</param>
        public void AddChildAndOpiekun(string dzieckaFirstname, string dzieckaLastname, int idGrupy, string opiekunaFirstname, string opiekunaLastname, int tel)
        {
            try
            {
                DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
                Dziecko dz = new Dziecko();
                dz.Imie = dzieckaFirstname;
                dz.Nazwisko = dzieckaLastname;
                int groupNr = Convert.ToInt32(idGrupy);
                dz.idGrupy = (from gr in db.Grupy where gr.Numer == groupNr select gr.idGrupy).SingleOrDefault();
                Opiekun op = new Opiekun();

                op.Imie = opiekunaFirstname;
                op.Nazwisko = opiekunaLastname;
                op.Telefon = tel;
                dz.Opiekun = op;

                db.AddToOpiekun(op);
                db.AddToDziecko(dz);
                db.SaveChanges();
            }
            catch (FaultException fe)
            {
                throw new FaultException(fe.Reason, fe.Code, "Exception in AddChildAndOpiekun");
            }
            catch (CommunicationException cex)
            {
                throw new CommunicationException("Exception in AddChildAndOpiekun " + cex.Message, cex.InnerException);
            }
            catch (Exception exe)
            {
                throw new Exception("Exception in AddChildAndOpiekun " + exe.Message, exe.InnerException);
            }
        }

        /// <summary>
        /// Adds the kind of the payment.
        /// </summary>
        /// <param name="typ">The type of payment.</param>
        /// <param name="rodzajCzest">The rodzaj czest.</param>
        /// <param name="nazwa">The name of payment.</param>
        /// <param name="kwota">The kwota.</param>
        public void AddPaymentKind(string typ, string rodzajCzest, string nazwa, double kwota)
        {
            try
            {
                DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
                RodzajeOplat rodzaje = new RodzajeOplat();
                var idTypy = (from typy in db.TypyOplat
                              where typy.NazwaTypuOplaty == typ
                              select typy.idTypyOplat).SingleOrDefault();
                rodzaje.idTypyOplat = idTypy;
                var idCzest = (from czest in db.Czestotliwosc
                               where czest.Nazwa == rodzajCzest
                               select czest.idCzestotliwosc).FirstOrDefault();
                rodzaje.idCzestotliwosc = idCzest;
                rodzaje.Kwota = kwota;
                rodzaje.NazwaRodzajuOplaty = nazwa;
                db.AddToRodzajeOplat(rodzaje);
                db.SaveChanges();
            }
            catch (FaultException fe)
            {
                throw new FaultException(fe.Reason, fe.Code, "Exception in AddPaymentKind");
            }
            catch (CommunicationException cex)
            {
                throw new CommunicationException("Exception in AddPaymentKind " + cex.Message, cex.InnerException);
            }
            catch (Exception exe)
            {
                throw new Exception("Exception in AddPaymentKind " + exe.Message, exe.InnerException);
            }
        }

        /// <summary>
        /// Gets the groups.
        /// </summary>
        /// <returns>The groups.</returns>
        public IEnumerable<int> GetGroups()
        {
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            IEnumerable<int> groups = from g in db.Grupy select g.Numer;
            return groups;
        }

        /// <summary>
        /// Adds the payment to child.
        /// </summary>
        /// <param name="dzieckaImie">The dziecka imie.</param>
        /// <param name="dzieckaNazwisko">The dziecka nazwisko.</param>
        /// <param name="opiekunaImie">The opiekuna imie.</param>
        /// <param name="opiekunaNazwisko">The opiekuna nazwisko.</param>
        /// <param name="rodzaj">The rodzaj pf payment.</param>
        /// <param name="miesiac">The miesiac.</param>
        /// <param name="terminPl">The termin platnosci.</param>
        public void AddPaymentToChild(string dzieckaImie, string dzieckaNazwisko, string opiekunaImie, string opiekunaNazwisko, string rodzaj, string miesiac, DateTime terminPl)
        {
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            Dziecko dziecko = new Dziecko();
            RodzajeOplat rodzaje = new RodzajeOplat();
            Miesiace m = new Miesiace();
            Naleznosci nal = new Naleznosci();
            dziecko = (from dzieckoTmp in db.Dziecko
                       where dzieckoTmp.Imie == dzieckaImie &&
                       dzieckoTmp.Nazwisko == dzieckaNazwisko &&
                       dzieckoTmp.Opiekun.Imie == opiekunaImie &&
                       dzieckoTmp.Opiekun.Nazwisko == opiekunaNazwisko
                       select dzieckoTmp).SingleOrDefault();

            rodzaje = (from p in db.RodzajeOplat
                       where p.NazwaRodzajuOplaty == rodzaj
                       select p).SingleOrDefault();
            if (rodzaje.Czestotliwosc.Nazwa == "Jednorazowe")
            {
                nal.idMiesiace = null;
            }
            else
            {
                m = (from p in db.Miesiace
                     where p.Nazwa == miesiac
                     select p).SingleOrDefault();
                nal.idMiesiace = m.idMiesiace;
            }
            nal.idDziecko = dziecko.IdDziecko;
            nal.DataRozliczenia = null;
            nal.idRodzajeOplat = rodzaje.idRodzajeOplat;
            nal.TerminPlatnosci = terminPl;
            int dniSzkolne = 1;
            var idCzestoOplaty = (from p in db.RodzajeOplat where p.idRodzajeOplat == rodzaje.idRodzajeOplat select p.idCzestotliwosc).SingleOrDefault();
            if (rodzaje.Czestotliwosc.Nazwa == "Dzienne")
            {
                dniSzkolne = (from p in db.Miesiace where p.idMiesiace == m.idMiesiace select p.DniSzkolne).SingleOrDefault();
            }
            nal.Kwota = (from czesto in db.Czestotliwosc
                         where czesto.idCzestotliwosc.Equals(idCzestoOplaty)
                         select czesto.Kod).SingleOrDefault().Equals("D")
                          ? (dniSzkolne * rodzaje.Kwota) : rodzaje.Kwota;
            db.AddToNaleznosci(nal);
            db.SaveChanges();
        }

        /// <summary>
        /// Gets the months.
        /// </summary>
        /// <returns>The months.</returns>
        public IEnumerable<string> GetMonths()
        {
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            IEnumerable<string> miesiace = from m in db.Miesiace select m.Nazwa;
            return miesiace;
        }

        /// <summary>
        /// Gets the kind of the class.
        /// </summary>
        /// <returns>Class kind.</returns>
        public IEnumerable<string> GetClassKind()
        {
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            IEnumerable<string> classKinds = from k in db.RodzajeOplat select k.NazwaRodzajuOplaty;
            return classKinds;
        }

        /// <summary>
        /// Gets the type of the payment.
        /// </summary>
        /// <returns>Payment type.</returns>
        public IEnumerable<string> GetPaymentType()
        {
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            IEnumerable<string> paymentType = from t in db.TypyOplat select t.NazwaTypuOplaty;
            return paymentType;
        }

        /// <summary>
        /// Gets the payment frequency.
        /// </summary>
        /// <returns>Payment frequency.</returns>
        public IEnumerable<string> GetPaymentFrequency()
        {
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            IEnumerable<string> paymentFrequency = from f in db.Czestotliwosc select f.Nazwa;
            return paymentFrequency;
        }

        /// <summary>
        /// Gets the child and opiekun from group.
        /// </summary>
        /// <param name="groupNr">The group nr.</param>
        /// <returns>Collection of childerens and parents</returns>
        public CustomCollection<DzieckoAndOpiekun> GetChildAndOpiekunByGroup(int groupNr)
        {
            CustomCollection<DzieckoAndOpiekun> result = new CustomCollection<DzieckoAndOpiekun>();
            DataTransfer.ChargeInSchoolEntities db = new DataTransfer.ChargeInSchoolEntities();
            IEnumerable<DzieckoAndOpiekun> resultV = from dz in db.Dziecko.AsEnumerable()
                                                     where dz.idGrupy == groupNr
                                                     select new DzieckoAndOpiekun(
                                                   dz.Imie,
                                                   dz.Nazwisko,
                                                   dz.Opiekun.Imie,
                                                   dz.Opiekun.Nazwisko);
            List<DzieckoAndOpiekun> l = resultV.ToList();
            result.AddRange(l);
            return result;
        }
    }
}
